﻿/*
Module Name:  Effect.cs
Project:      ScriptManager
Copyright (C) 2012 Felipe Ramos

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using System.IO;
using System.Collections.Generic;
using System;

namespace ScriptManager.Scripting
{
    /// <summary>
    /// Effect scriptable object. Takes in a path to effect script and loads values for the EffectKeys defined.
    /// </summary>
    public class Effect : IScript<EffectKeys>
    {
        public Effect(string path, Rectangle region)
        {
            ScriptPath = path;
            IsAlive = false;
            Region = region;
        }

        /// <summary>
        /// Load effect script definition and any support files.
        /// </summary>
        /// <param name="content">ContentManager for loading any effect textures needed.</param>
        public void Load(ContentManager content)
        {
            Values = new Dictionary<EffectKeys, string>(4);

            using (var reader = new StreamReader(TitleContainer.OpenStream(ScriptPath)))
            {
                while (reader.Peek() > 0)
                {
                    string[] scriptParameters = reader.ReadLine().Split(':');
                    EffectKeys paramKey =
                        (EffectKeys)Enum.Parse(typeof(EffectKeys), scriptParameters[0].Trim().ToLower());

                    switch (paramKey)
                    {
                        case EffectKeys.name:
                        case EffectKeys.path:
                        case EffectKeys.frames:
                        case EffectKeys.duration:
                        case EffectKeys.format:
                            Values.Add(paramKey, scriptParameters[1].Trim());
                            break;
                    }
                }
            }

            Duration = Convert.ToInt32(Values[EffectKeys.duration]);
            Frames = Convert.ToInt32(Values[EffectKeys.frames]);
            Textures = new List<Texture2D>(Frames);
            for (int i = 1; i <= Frames; i++)
                Textures.Add(content.Load<Texture2D>(Values[EffectKeys.path]  +
                    string.Format(Values[EffectKeys.format], i)));
        }

        /// <summary>
        /// Update effects animation frame.
        /// </summary>
        /// <param name="gametime">GameTime</param>
        public void Update(GameTime gametime)
        {
            if (IsAlive)
            {
                Elapsed += gametime.ElapsedGameTime.Milliseconds;

                if (Elapsed / 1000f > Duration)
                {
                    Elapsed = 0;
                    IsAlive = false;
                }
                else
                {
                    FrameIndex += 1;
                    if (FrameIndex >= Frames - 1)
                        FrameIndex = 0;
                }
            }
        }

        /// <summary>
        /// Draw effect texture for FrameIndex.
        /// </summary>
        /// <param name="gameTime">GameTime</param>
        /// <param name="spriteBatch">SpriteBatch</param>
        public void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
                spriteBatch.Begin();
                spriteBatch.Draw(Textures[FrameIndex],
                    Region,
                    Color.White);
                spriteBatch.End();
        }

        public string ScriptPath { get; set; }
        public Rectangle Region { get; private set; }
        public bool IsAlive { get; set; }
        public int Duration { get; private set; }
        public int Frames { get; private set; }
        public int FrameIndex { get; private set; }
        public List<Texture2D> Textures { get; private set; }
        public float Elapsed { get; private set; }
        public Dictionary<EffectKeys, string> Values { get; set; }
    }
}
